// 文件名：list_splice_scheduler.cpp
// 目的：演示使用 std::list::splice 以 O(1) 代价在队列间移动任务，构建简单调度器。
// 队列：
//   - ready_  ：就绪队列（可立即运行）；
//   - waiting_：等待队列（I/O/依赖阻塞的任务）；
// 操作：
//   - addReady(task)：添加到就绪队列尾部；
//   - waitCurrent()：将就绪队列头部任务移动到等待队列尾部（O(1) splice）；
//   - wakeAll()：将所有等待任务移动回就绪队列尾部（O(1) splice 整段）；
//   - tick()：执行一个就绪任务（取头、弹出、打印）。
// 特性：使用 splice 在同一容器类型间转移节点，不涉及元素拷贝/移动构造，迭代器/引用稳定。

#include <list>
#include <string>
#include <iostream>

struct Task {
    std::string name;
};

class Scheduler {
public:
    // 新任务进入就绪队列（FIFO 尾部）
    void addReady(Task task) {
        ready_.push_back(std::move(task));
    }

    // 当前就绪任务进入等待（将 ready_ 的头结点 splice 到 waiting_ 的尾部）
    void waitCurrent() {
        if (!ready_.empty()) {
            waiting_.splice(waiting_.end(), ready_, ready_.begin());
        }
    }

    // 唤醒所有等待任务（整段 splice 到 ready_ 尾部）
    void wakeAll() {
        ready_.splice(ready_.end(), waiting_);
    }

    // 执行一步调度：若就绪为空则提示，否则取出并运行一个任务
    void tick() {
        if (ready_.empty()) {
            std::cout << "No ready tasks\n";
            return;
        }
        Task task = std::move(ready_.front()); // 取出任务（此处可模拟执行）
        ready_.pop_front();
        std::cout << "Run task: " << task.name << '\n';
    }

    // 打印两个队列的内容
    void dump() const {
        auto print = [](const std::list<Task>& lst) {
            std::cout << '[';
            bool first = true;
            for (const auto& task : lst) {
                if (!first) std::cout << ", ";
                std::cout << task.name;
                first = false;
            }
            std::cout << ']';
        };
        std::cout << "Ready ";  print(ready_);
        std::cout << "  Waiting "; print(waiting_);
        std::cout << '\n';
    }

private:
    std::list<Task> ready_;
    std::list<Task> waiting_;
};

int main() {
    Scheduler scheduler;
    scheduler.addReady({"render"});
    scheduler.addReady({"physics"});
    scheduler.addReady({"network"});
    scheduler.dump();

    scheduler.tick();        // 执行 render
    scheduler.waitCurrent(); // physics 等待 I/O
    scheduler.dump();

    scheduler.tick();        // 执行 network
    scheduler.wakeAll();     // physics 唤醒
    scheduler.dump();

    scheduler.tick();        // 执行 physics
    scheduler.tick();        // 空
    return 0;
}